home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ghostscript / 8.64 / Resource / Init / gs_cmap.ps < prev    next >
Encoding:
Text File  |  2009-04-17  |  17.3 KB  |  550 lines

  1. %    Copyright (C) 1995, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: gs_cmap.ps 8954 2008-08-08 04:22:38Z ray $
  14. % ProcSet for implementing CMap resources.
  15. % When this is run, systemdict is still writable.
  16.  
  17. % NOTE: Rearranged fonts are not implemented yet.
  18.  
  19. [
  20.    /CMERGE_DEBUG
  21.    /USE_CIDCHAR_AS_RANGE
  22. ] {dup where {pop pop} { currentdict exch //false def pop } ifelse} forall
  23.  
  24. % ---------------- Public operators ---------------- %
  25.  
  26. /.rewriteTempMapsNotDef {
  27.   %
  28.   % Before building .CodeMapData from .TempMaps,
  29.   % we need to replace dst type codes in the notdef map with the value 3,
  30.   % which corresponds to CODE_VALUE_NOTDEF, see gxfcmap.h .
  31.   %
  32.   CMAPDEBUG { (rewriting TempMapsNotDef\n) print flush } if
  33.   .TempMaps 2 get
  34.   dup length 0 gt {
  35.     0 get
  36.     CMAPDEBUG { (...original...\n) print flush } if
  37.     1 5 2 index length 1 sub {
  38.       { 1 index exch get 2 3 put } stopped
  39.       { CMAPDEBUG { (cannot rewrite\n) print flush } if }
  40.       { CMAPDEBUG { (rewrite\n) print flush } if } ifelse
  41.     } for
  42.   } if
  43.   pop
  44.   CMAPDEBUG { (...FINISHED...\n) print } if
  45. } bind def
  46.  
  47. /.composefontdict {        % <name> <cmap|cmapname> <fonts> composefont <name> <font_dict>
  48.   10 dict begin
  49.     /CMap 2 index dup type /dicttype ne { /CMap findresource } if def
  50.     /FDepVector 1 index cvlit def    % temporarily
  51.     /Encoding [ 0 1 FDepVector length 1 sub { } for ] def
  52.     /FontInfo 1 dict def % for .processToUnicode in pdf_font.ps .
  53.     /FDepVector [ 0 1 FDepVector length 1 sub {
  54.         % Stack: name cmap[name] fonts /FDepVector [ fonts... i
  55.       FDepVector 1 index get
  56.       dup type /dicttype ne {
  57.     dup /CIDFont resourcestatus {
  58.       pop pop /CIDFont
  59.     } {
  60.       /Font
  61.     } ifelse findresource
  62.       } if
  63.       exch CMap /FontMatrices get dup length 2 index gt {
  64.     exch get dup //null eq { pop } { makefont } ifelse
  65.       } {
  66.     pop pop
  67.       } ifelse
  68.     } for ] readonly def
  69.     /FMapType 9 def
  70.     /FontMatrix matrix def
  71.     /FontName 3 index def
  72.     CMap /WMode .knownget { /WMode exch def } if
  73.     /FontType 0 def
  74.   pop pop currentdict end 
  75. } bind odef
  76.  
  77. % composefont doesn't appear in CMap files -- it's documented in
  78. % the "PostScript Language Reference Manual Supplement".
  79. /composefont {        % <name> <cmap|cmapname> <fonts> composefont <font>
  80.   .composefontdict /Font defineresource
  81. } bind def
  82.  
  83. % ---------------- CMap operators ---------------- %
  84.  
  85. 40 dict begin
  86.  
  87. % Our internal .CodeMapData structure closely mirrors the structures
  88. % defined in gxfcmap.h (q.v.).  () indicate a string, [] indicate an array,
  89. % ? indicates a Boolean, # indicates an integer, {} for grouping.
  90. %    [[[(first) (last) ...]+]        % code space ranges
  91. %     [[(prefix) (key_size,?is_range,value_type,value_size) (keys...)
  92. %       {(values...) | [value ...]} #font_index ]+]    % code mappings
  93. %      ...]
  94. %     <<same>>        % notdef mappings
  95. %    ]
  96. % FontMatrices is the array of matrices defined by begin/endusematrix.
  97. % All of the arrays and strings are read-only after they have been built.
  98. %
  99. % Note that the code in zfcmap.c that constructs the C structures from
  100. % the PostScript structures has intimate knowledge of the above format.
  101.  
  102. % ****** NOTE: The code currently only handles "well-behaved" CMaps:
  103. %    - CID values only (no bfchars), 16-bit
  104. %    - Entries (both code space and map) must be sorted
  105. %    - Only the last byte must vary in each map range, except for
  106. %    the identity mapping
  107.  
  108. % ------ Font-level operators ------ %
  109.  
  110. /begincmap {        % - begincmap -
  111.   /.CodeMapData [[[]] [[]] [[]]] def
  112.   /FontMatrices [] def
  113.   /.FontIndex 0 def
  114.   /.TempMaps [20 dict 50 dict 50 dict] def
  115.   /CodeMap //null def        % for .buildcmap
  116. } bind def
  117.  
  118. /endcmap {        % - endcmap -
  119.   .rewriteTempMapsNotDef
  120.  
  121.   CMAPDEBUG {
  122.     2 (*** undefined charmap ***)
  123.     1 (*** defined charmap ***)
  124.     0 (*** code space ranges ***)
  125.     3 { =
  126.       .TempMaps exch get
  127.       0 1 2 index length 1 sub {
  128.         dup == (\t) print
  129.         1 index exch get ==
  130.       } for
  131.       pop
  132.     } repeat
  133.   } if
  134.   
  135.   /.CodeMapData dup load [ exch
  136.     .TempMaps aload pop begin begin begin 
  137.     {
  138.       [ exch aload pop
  139.         0 1 currentdict length 1 sub { 
  140.            currentdict exch get 
  141.         } for 
  142.       ]
  143.       end
  144.     } forall
  145.   ] .endmap def
  146.  
  147.   CMAPDEBUG {
  148.     (*** Content of .CodeMapData ***) =
  149.     0 .CodeMapData { exch dup == 1 add exch (\t) print == } forall
  150.     pop
  151.   } if
  152.  
  153.   currentdict /.TempMaps undef
  154.   /FontMatrices FontMatrices .endmap def
  155. } bind def
  156.  
  157. /.endmap {        % <map> .endmap <map>
  158.   dup type /arraytype eq {
  159.     % This might be a shared read-only array inherited via usecmap.
  160.     % Don't try to update its elements if this is the case.
  161.     dup wcheck {
  162.       0 1 2 index length 1 sub {
  163.     2 copy 2 copy get .endmap put pop
  164.       } for readonly
  165.     } if
  166.   } {
  167.     dup type /stringtype eq { readonly } if
  168.   } ifelse
  169. } bind def
  170.  
  171. /.appendmap {        % -mark- <elt> ... <array#> .appendmap -
  172.   .TempMaps exch get counttomark 1 add 1 roll
  173.   ] 1 index length exch put
  174. } bind def
  175.  
  176. /begincodespacerange {    % <count> begincodespacerange -
  177.   pop mark
  178. } bind def
  179.  
  180. /endcodespacerange {    % <code_lo> <code_hi> ... endcodespacerange -
  181.   0 .appendmap
  182. } bind def
  183.  
  184. /usecmap {        % <CMap_name> usecmap -
  185.   /CMap findresource dup
  186.         % Copy the top level of .CodeMapData
  187.   /.CodeMapData exch /.CodeMapData get copyarray def
  188.   /FontMatrices exch /FontMatrices get copyarray def
  189. } bind def
  190.  
  191. /usefont {        % <fontID> usefont -
  192.   /.FontIndex exch def
  193. } bind def
  194.  
  195. /beginusematrix {    % <fontID> beginusematrix -
  196.   FontMatrices wcheck not FontMatrices length 2 index le or {
  197.     FontMatrices length 1 index 1 add .max array
  198.     dup 0 FontMatrices putinterval
  199.     /FontMatrices exch def
  200.   } if
  201. } bind def
  202.  
  203. /endusematrix {        % <matrix> endusematrix -
  204.   FontMatrices 3 1 roll put
  205. } bind def
  206.  
  207. % ------ Rearranged font operators ------ %
  208.  
  209. /beginrearrangedfont {    % <font_name> <font*> beginrearrangedfont -
  210.   10 dict begin
  211.   /.FontNames exch def
  212.   /.FontName exch def
  213.   begincmap
  214. } bind def
  215. /endrearrangedfont {    % - endrearrangedfont -
  216.   (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
  217.   FontName .FontNames 0 get findfont end definefont pop
  218. } bind def
  219.  
  220. % ------ Character name/code selector operators ------ %
  221.  
  222. /beginbfchar {        % <count> beginbfchar -
  223.   pop mark
  224. } bind def
  225. /endbfchar {        % <code> <to_code|charname> ... endbfchar
  226.   counttomark 2 idiv {
  227.     counttomark -2 roll        % process in correct order
  228.     .addbfchar
  229.   } repeat 1 .appendmap
  230. } bind def
  231.  
  232. /beginbfrange {        % <count> beginbfrange -
  233.   pop mark
  234. } bind def
  235. /endbfrange {        % <code_lo> <code_hi> <to_code|(charname*)> ...
  236.             %   endbfrange -
  237.   counttomark 3 idiv {
  238.     counttomark -3 roll        % process in correct order
  239.     dup type dup /arraytype eq exch /packedarraytype eq or {
  240.             % Array value, split up.
  241.       exch pop {
  242.             % Stack: code to_code|charname
  243.     1 index exch .addbfchar
  244.             % Increment the code.  As noted above, we require
  245.             % that only the last byte vary, but we still must
  246.             % mask it after incrementing, in case the last
  247.             % value was 0xff.
  248.             % Stack: code prefix params key value fontindex
  249.     6 -1 roll dup length string copy
  250.     dup dup length 1 sub 2 copy get 1 add 255 and put
  251.       } forall pop
  252.     } {
  253.             % Single value, handle directly.
  254.       .addbfrange
  255.     } ifelse
  256.   } repeat 1 .appendmap
  257. } bind def
  258.  
  259. /.addbfchar {        % <code> <to_code|charname> .addbfchar
  260.             %   <prefix> <params> <key> <value> <font_index>
  261.   1 index exch .addbfrange
  262. } bind def
  263. /.addbfrange {        % <code_lo> <code_hi> <to_code|charname>
  264.             %   .addbfrange <<same as .addbfchar>>
  265.   4 string dup 3
  266.   3 index type /nametype eq {
  267.     2 index 2 1 put % dst = CODE_VALUE_GLYPH, see gxfcmap.h .
  268.     4 -1 roll 1 array astore 4 1 roll 4
  269.   } {
  270.     2 index 2 2 put % dst = CODE_VALUE_CHARS, see gxfcmap.h .
  271.     3 index length
  272.   } ifelse put
  273.             % Stack: code_lo code_hi value params
  274.   3 index 3 index eq {
  275.             % Single value.
  276.     3 -1 roll pop exch () exch
  277.   } {
  278.             % Range.
  279.     dup 0 1 put dup 1 1 put
  280.     4 2 roll
  281.     dup dup length 1 sub 0 exch getinterval 5 1 roll    % prefix
  282.             % Stack: prefix value params code_lo code_hi
  283.     2 { exch dup length 1 sub 1 getinterval } repeat concatstrings
  284.     3 -1 roll
  285.   } ifelse
  286.   .FontIndex
  287. } bind def
  288.  
  289. % ------ CID selector operators ------ %
  290.  
  291. /begincidchar {        % <count> begincidchar -
  292.   pop mark
  293. } bind def
  294. /endcidchar {        % <code> <cid> ... endcidchar -
  295.   1 .endmapchars
  296. } bind def
  297.  
  298. /begincidrange {    % <count> begincidrange -
  299.   pop mark
  300. } bind def
  301. /endcidrange {        % <code_lo> <code_hi> <cid_base> ... endcidrange -
  302.   1 .endmapranges
  303. } bind def
  304.  
  305. /.endmapchars {         % -mark- <code> <cid> ... <map#> .endmapchars -
  306.   counttomark 1 add 1 roll
  307.   counttomark 2 idiv {
  308.     counttomark -2 roll         % process in correct order
  309.     exch        % <cid> <code>
  310.                 % Construct prefix, params, key, value, font_index
  311.     dup length 1 eq {   % 1-byte
  312.       <00 00 00 02> ()  % <prefix> <param> <null_key>
  313.     } {                 % N-byte
  314.       dup 0 1 getinterval exch  % make 1-byte prefix
  315.       4 string dup 0
  316.       USE_CIDCHAR_AS_RANGE {
  317.         <00 01 00 02>   % skelton for param
  318.       } {
  319.         <00 00 00 02>   % skelton for param
  320.       } ifelse
  321.       putinterval
  322.       exch              % <prefix> <param> <code>
  323.       dup length        % <prefix> <param> <code> N
  324.       1 sub             % <prefix> <param> <code> N-1
  325.       dup               % <prefix> <param> <code> N-1 N-1
  326.       3 index           % <prefix> <param> <code> N-1 N-1 <param>
  327.       exch              % <prefix> <param> <code> N-1 <param> N-1
  328.       0 exch            % <prefix> <param> <code> N-1 <param> 0 N-1
  329.       put               % <prefix> <param'> <code> N-1
  330.       1 exch            % <prefix> <param'> <code> 1 N-1
  331.       getinterval       % <prefix> <param'> <key>
  332.  
  333.       USE_CIDCHAR_AS_RANGE {
  334.         dup length 2 mul string % <key> <dkey>
  335.         dup                     % <key> <dkey> <dkey>
  336.         2 index                 % <key> <dkey> <dkey> <key>
  337.         0 exch putinterval      % <key> <dkey'>
  338.         dup                     % <key> <dkey'> <dkey'>
  339.         3 -1 roll               % <dkey'> <dkey'> <key>
  340.         dup length              % <dkey'> <dkey'> <key> N-1
  341.         exch putinterval        % <dkey''>
  342.       } if
  343.  
  344.     } ifelse
  345.  
  346.     4 -1 roll           % <prefix> <param'> <key> <cid>
  347.     .endmapvalue        % <prefix> <param'> <key> <hex_cid> <font_idx>
  348.     % prefix params keys value fontindex
  349.     counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item)
  350.        4 index 10 index eq      % compare prefix
  351.        4 index 10 index eq and  % compare params
  352.        1 index 7 index eq and   % compare fontindex
  353.         {
  354.           CMAPDEBUG { (merge! char\n) print } if
  355.           pop 4 2 roll pop pop
  356.            % prefix params keys value fontindex keys2 value2
  357.           5 -1 roll 3 -1 roll concatstrings
  358.            % prefix params value fontindex value2 keys'
  359.           4 -1 roll 3 -1 roll concatstrings
  360.            % prefix params fontindex keys' values'
  361.           3 -1 roll
  362.         } if
  363.      } if % end of 2 (or more) ranges
  364.     CMERGE_DEBUG {
  365.     ( prefix:) print 4 index =only
  366.     ( param:) print 3 index =only
  367.     ( key:) print 2 index =only
  368.     ( hex_cid:) print 1 index =only
  369.     ( font_idx:) print 0 index == flush
  370.     } if
  371.   } repeat
  372.   counttomark 2 add -1 roll .appendmap
  373. } bind def
  374.  
  375. /.endmapranges {    % -mark- <code_lo> <code_hi> <cid_base> ... <map#>
  376.             %   .endmapranges -
  377.   counttomark 1 add 1 roll
  378.   counttomark 3 idiv {
  379.     counttomark -3 roll        % process in correct order
  380.         % Construct prefix, params, key_lo, key_hi, value, font_index
  381.     3 1 roll    % <cid_base> <code_lo> <code_hi>
  382.         %        prefix    key
  383.         % 1-byte code:    ()    .
  384.         % 1-byte range:    ()    .
  385.         % N-byte code:    .    (*)
  386.         % N-byte range:    (*)    (*)
  387.     dup 2 index eq {    % <code_lo> == <code_hi>
  388.                    % 0: prefix_len for 1-byte code
  389.                    % 1: prefix_len for N-byte code
  390.        dup length 1 eq { 0 } { 1 } ifelse
  391.     } {            % <code_lo> != <code_hi>
  392.                  % calculate prefix_len for *-byte range
  393.        dup length 1 sub % <cid_base> <code_lo> <code_hi> <code_len-1>
  394.        0        % initial value for N
  395.        {        % <cid_base> <code_lo> <code_hi> (code_len-1)  N
  396.            dup 2 index ge { exit } if % if (N >= len - 1) exit
  397.            3 index 1 index get    % N-th byte of code_lo
  398.            3 index 2 index get    % N-th byte of code_hi
  399.            eq { 1 add } { exit } ifelse
  400.        } loop
  401.        exch pop     % discard <code_len-1>
  402.     } ifelse
  403.                 % cid_base code_lo code_hi prefix_len
  404.  
  405.     % Althogh Adobe CPSI with native CID/CMap support accept
  406.     % multi-dimensional range specification in notdef & cidrange
  407.     % (and CID is calculated as relative position in multi-dimensional
  408.     % range), but older CPSI & ATM cannot handle it.
  409.     % 
  410.     % GS accepts such specification, but it's recommended to keep
  411.     % from using this feature for notdef & cidrange.
  412.     % Following is a disabler of this feature.
  413.     % -------------------------------------------------------------
  414.     % counttomark 1 add index     % get map#
  415.     % 0 ne {            % if not codespacerange
  416.     %   1 index length         % get code length
  417.     %   1 index             % get prefix length
  418.     %   sub            % calculate key length
  419.     %   1 gt {            % if (key_len > 1),
  420.     %      (.endmapranges error) = flush
  421.     %      (multi-dimensional range specification is used out of codespacerange)
  422.     %      = flush
  423.     %      (/) =only
  424.     %      CMapName CMapName length string cvs =only
  425.     %      (: <) =only
  426.     %      2 index (%stdout) (w) file exch writehexstring
  427.     %      (> <) =only
  428.     %      1 index (%stdout) (w) file exch writehexstring
  429.     %      (>\n) =only flush
  430.     %      quit
  431.     %   } if
  432.     % } if
  433.     % -------------------------------------------------------------
  434.  
  435.     1 index exch 0 exch getinterval
  436.                 % cid_base code_lo code_hi prefix
  437.     dup length 3 index length exch sub
  438.                 % cid_base code_lo code_hi prefix range_len
  439.     dup 255 gt {
  440.        (too long coderange specification for current GS\n) print
  441.        /.endmapranges cvx /rangecheck signalerror
  442.     } if
  443.     <00 01 00 02> 4 string copy    % create initialized param
  444.     dup 0 4 -1 roll put        % put range_len into param
  445.  
  446.     % get key_hi
  447.     3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval
  448.  
  449.     % get key_lo
  450.     4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval
  451.  
  452.     % make "keys" (concatenated key_lo + key_hi)
  453.     exch concatstrings
  454.  
  455.     % 
  456.     4 -1 roll
  457.     .endmapvalue
  458.  
  459.         % See if we can merge with the previous value.
  460.         % The prefix, params, and font index must match.
  461.     % prefix params keys value fontindex
  462.     counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item)
  463.        4 index 10 index eq    % compare prefix
  464.        4 index 10 index eq and    % compare params
  465.        1 index 7 index eq and    % compare fontindex
  466.     {
  467.           CMAPDEBUG { (merge!\n) print } if
  468.       pop 4 2 roll pop pop
  469.            % prefix params keys value fontindex keys2 value2
  470.       5 -1 roll 3 -1 roll concatstrings
  471.            % prefix params value fontindex value2 keys'
  472.       4 -1 roll 3 -1 roll concatstrings
  473.            % prefix params fontindex keys' values'
  474.       3 -1 roll
  475.     } if
  476.      } if % end of 2 (or more) ranges
  477.   } repeat
  478.   counttomark 2 add -1 roll .appendmap
  479. } bind def
  480.  
  481. /.endmapvalue {        % <cid> .endmapvalue (hi,lo) .FontIndex
  482.   2 string dup 0 3 index -8 bitshift put    % value
  483.   dup 1 4 -1 roll 255 and put
  484.   .FontIndex        % font_index
  485. } bind def
  486.  
  487. % ------ notdef operators ------ %
  488.  
  489. /beginnotdefchar {    % <count> beginnotdefchar -
  490.   pop mark
  491. } bind def
  492. /endnotdefchar {    % <code> <cid> ... endnotdefchar -
  493.   2 .endmapchars
  494. } bind def
  495.  
  496. /beginnotdefrange {    % <count> beginnotdefrange -
  497.   pop mark
  498. } bind def
  499. /endnotdefrange {    % <code_lo> <code_hi> <cid> ... endnotdefrange -
  500.   2 .endmapranges
  501. } bind def
  502.  
  503. % ---------------- Resource category definition ---------------- %
  504.  
  505. currentdict end
  506.  
  507. languagelevel exch 2 .setlanguagelevel
  508.  
  509. /CMap /Generic /Category findresource dup length dict .copydict
  510. dup /InstanceType /dicttype put
  511. dup /DefineResource {
  512.         % The AdobePS5 Windows driver emits code that attempts to
  513.         % create CMaps without the required CMapName entry.
  514.         % Work around this here.
  515.   dup /CMapName known not {
  516.     dup wcheck not {
  517.       .currentglobal exch dup wcheck .setglobal
  518.       dup length dict .copydict exch .setglobal
  519.     } if
  520.     dup gcheck 2 index gcheck not and {
  521.       exch .currentglobal exch //true .setglobal
  522.       dup length string copy exch .setglobal exch
  523.     } if dup /CMapName 3 index put
  524.   } if
  525.   % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this.
  526.   % With the above, we can actually tolerate: /name << >> defineresource
  527.   dup /CIDSystemInfo known not {
  528.     dup wcheck not {
  529.       .currentglobal exch dup wcheck .setglobal
  530.       dup length dict .copydict exch .setglobal
  531.     } if
  532.     dup /CIDSystemInfo [ //null ] put
  533.   } if
  534.   dup /CodeMap .knownget { //null eq { .buildcmap } if } if
  535.   /Generic /Category findresource /DefineResource get exec
  536. } bind put
  537. /Category defineresource pop
  538.     % We might have loaded CID font support already.
  539. /CIDInit /ProcSet 2 copy { findresource } .internalstopped
  540.     % An interior `stopped' might have reset VM allocation to local.
  541. //true .setglobal
  542.  { pop pop 3 -1 roll }
  543.  { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
  544. ifelse exch defineresource pop
  545.  
  546. .setlanguagelevel
  547.